// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "EnhancedInputComponent.h"
#include "InputConfig.h"
#include "AuraInputComponent.generated.h"

class UInputConfig;
/**
 * 自定义的增强输入组件
 */
UCLASS()
class AURA_API UAuraInputComponent : public UEnhancedInputComponent
{
	GENERATED_BODY()

public:
	/**
	 * 绑定函数,将InputConfig的TaggedInputActions的InputAction绑定到成员函数,绑定的同时传递对应标签
	 * @param InputConfig
	 * @param Object
	 * @param PressedFunc ETriggerEvent::Started绑定的函数
	 * @param ReleaseFunc ETriggerEvent::Completed绑定的函数
	 * @param   HoldFunc ETriggerEvent::Triggered 绑定的函数
	 */
	template <class UserClass, typename PressedFuncType, typename ReleaseFuncType, typename HoldFuncType>
	void BindAbilityAction(UInputConfig* InputConfig, UserClass* Object, PressedFuncType PressedFunc,
	                       ReleaseFuncType ReleaseFunc, HoldFuncType HoldFunc);
};


template <class UserClass, typename PressedFuncType, typename ReleaseFuncType, typename HoldFuncType>
void UAuraInputComponent::BindAbilityAction(UInputConfig* InputConfig, UserClass* Object, PressedFuncType PressedFunc,
                                            ReleaseFuncType ReleaseFunc, HoldFuncType HoldFunc)
{
	check(InputConfig)

	for (FTaggedInputAction& Action : InputConfig->AbilityTaggedInputActions)
	{
		if (Action.InputAction && Action.InputTag.IsValid())
		{
			if (PressedFunc)
			{
				/**
				 *  Triggered 将在事件生命周期每一帧触发
				 *  Started 在事件开始时触发，Triggered也可能在同一帧触发，但是Started会在它之前触发
				 *  这里用class 指要绑定到的类
				 *  这里应该是绑定的时候传了payload, TODO:tag和inputaction原理
				 */
				BindAction(Action.InputAction, ETriggerEvent::Started, Object, PressedFunc, Action.InputTag);
			}

			if (HoldFunc)
			{
				BindAction(Action.InputAction, ETriggerEvent::Triggered, Object, HoldFunc, Action.InputTag);
			}

			if (ReleaseFunc)
			{
				BindAction(Action.InputAction, ETriggerEvent::Completed, Object, ReleaseFunc, Action.InputTag);
			}
		}
	}
}
